﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using xKnight.Analyzing.BaseAnalyze;
using xKnight.Analyzing.EncodedXss;
using xKnight.Analyzing.SimpleXss;
using xKnight.Analyzing.Xss;
using xKnight.Attacking;
using xKnight.Data;
using xKnight.Models;

namespace xKnight.Analyzing
{
    public delegate void AnalyzeCompletedEventHandler(object sender, AnalyzeCompletedEventArgs e);
    public delegate void AnalyzeStartedEventHandler(object sender, AnalyzeStartedEventArgs e);
    public delegate void AnalyzeAnnouncedEventHandler(object sender, AnalyzeAnnouncedEventArgs e);

    public class AnalyzeManager
    {
        #region Fields

        private int _attackId;

        #endregion

        #region Events

        public event AnalyzeCompletedEventHandler AnalyzeCompleted;
        public event AnalyzeStartedEventHandler AnalyzeStarted;
        public event AnalyzeAnnouncedEventHandler AnalyzeAnnounced;

        #endregion

        #region Constructors

        public AnalyzeManager(int attackId)
        {
            _attackId = attackId;
        }

        #endregion

        #region Interface

        public void Analyze()
        {
            Attack attack = DataLayer.GetAttack(_attackId);
            CheckExistanceOfAttack(attack);

            Analyzer analyzer = AnalyzerFactory.CreateAnalyzer(attack);

            analyzer.AnalyzeAnnounced += AnalyzeAnnouncedHandler;
            analyzer.AnalyzeCompleted += AnalyzeCompletedHandler;
            analyzer.AnalyzeStarted += AnalyzeStartedHandler;
         
            analyzer.AnalyzeAsync();
        }

        #endregion

        #region EventHandler

        void AnalyzeStartedHandler(object sender, AnalyzeStartedEventArgs e)
        {
            OnAnalyzeStarted(e);
        }

        void AnalyzeCompletedHandler(object sender, AnalyzeCompletedEventArgs e)
        {
            OnAnalyzeCompleted(e);
        }

        void AnalyzeAnnouncedHandler(object sender, AnalyzeAnnouncedEventArgs e)
        {
            OnAnalyzeAnnounced(e);
        }

        #endregion

        #region Events Raiser

        private void OnAnalyzeCompleted(AnalyzeCompletedEventArgs e)
        {
            if (AnalyzeCompleted != null)
            {
                AnalyzeCompleted(this, e);
            }
        }

        private void OnAnalyzeStarted(AnalyzeStartedEventArgs e)
        {
            if (AnalyzeStarted != null)
            {
                AnalyzeStarted(this, e);
            }
        }

        private void OnAnalyzeAnnounced(AnalyzeAnnouncedEventArgs e)
        {
            if (AnalyzeAnnounced != null)
            {
                AnalyzeAnnounced(this, new AnalyzeAnnouncedEventArgs(e.AnnounceItem));
            }
        }

        #endregion

        #region Private Methods

        private void CheckExistanceOfAttack(Attack attack)
        {
            if (attack == null)
                throw new InvalidDataException(string.Format("no attack with id {0} was found in the database.", _attackId));
        }

        #endregion
    }
}
